/*
 * This file is part of the openHiTLS project.
 *
 * openHiTLS is licensed under the Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *
 *     http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
#include "hitls_build.h"
#if defined(HITLS_CRYPTO_CMVP_ISO19790) || defined(HITLS_CRYPTO_CMVP_FIPS)
#include <string.h>
#include "crypt_cmvp_selftest.h"
#include "cmvp_common.h"
#include "err.h"
#include "crypt_errno.h"
#include "crypt_algid.h"
#include "crypt_eal_pkey.h"
#include "bsl_err_internal.h"
#include "crypt_utils.h"
#include "securec.h"
#include "bsl_sal.h"

#define BITS_OF_BYTE 8

typedef struct {
    const char *rnd;
    const char *sk;
    const char *pk;
    const char *context;
    const char *msg;
    const char *sig;
    int32_t preHashId;
    int32_t algId;
    int32_t type;
} CMVP_SlhdsaSignVector;

static const CMVP_SlhdsaSignVector SLHDSA_VECTOR[] = {
    {
        // https://github.com/usnistgov/ACVP-Server/tree/master/gen-val/json-files/SLH-DSA-sigGen-FIPS205
        .rnd = "FD3FE9ADC298FAD0BF5A08D804C690B1",
        .sk = "F9FFBDE3D5FB47C2669823076777A941B810BE27FEF66DD4353B4A21DC972842EA5EE0F3E9B301B5CC32814C8AC6CDBD8BE5D429B0104F2F0A929099F687A74C",
        .pk = "EA5EE0F3E9B301B5CC32814C8AC6CDBD8BE5D429B0104F2F0A929099F687A74C",
        .context = "F29200E32E0DCCC92F029503DF3C878E340569C54169A31F7704A16EEBDF5667D0A5DB865F486F67052B1765B772D461C9F4B75B2D6056CD185F2C9D74D1F446674D75B49D5082EC6097269837BC7FA3A2163FE026BEB4455A79D7E135D0FF2BC44E213715767808D4DD1AE2A6B147F041616D74FDB89589848B2B155957CA7B79CC497EACC1050F8A3C98BB4839D1858F",
        .msg = "3039FF4B78F80DCDCEF91B8602456D99621B7736D6207A60B9EDF5C662587DA6B2189FC463DE94448055CD3C65C877325F1EA0B77737A8CFFD63290D3D8E229B35804F7A78CDB703D2EE6E7EF078C3E2FA325585F3B326019317911BE16633EFD4BDB429AB7265B4A4936A9E393BE78F7E0B74707DF758EAAAFAECDD815C973C8DA8BAD70842EE6EA3D27D4C9DD1FC7FF5137779A3C0978E95BD6B99E0088721DF086F35BBDCA3F68417301585EEA71594CDE5097D7744FCDE75B4AC387386D4E8023A45E6904DDA1CF4F0E7BC75034969A30C67DC6F231A4D56C608B7BFEB75FFED8B893811B9A134C178A1919252A47E6B6B23E885C1738C7257A031829C9596827A0F1A81B5D5C7F5EC9EE3B08CA5F6F88A545581F779FDA50BEDE7819621605C511E37489D08BFC1A4E0FFBF1997603E21C8A3FCF1E7A0B158B78A75976CD5EB5DFC47EDE317C02E514768982B555D96637EED6B0DBD58990B1B605D3711080D782A14762DC4BC0F33B1BA4A80ACCDB915C2869F7A4E16717375B1A027F4DF0B92E944F80E7258EA1E68B9232FCC0EBCBB8851171C9AF7BD2323E986AEDA77EDD4E9178F68884167D9A33A710B39955DFC607B9EE2B4F5A978AD814FDA328D59D9C55DC4290B1D362633CB11446F6AA473C3B93C3350B231AE409A85BF679BA5B47FE175DD0820B69DAFEF94E6A3EA133340B775D842D8BB3A3BCD4AC1BAE516C8B2B52E839DE52B39927F0C0CED6D7C8B5C3FA57D645769AD6413C3335A481CBBFB82531F756F73E635D930AC851F4EFE01A40AD6A1114B05D4A3F210CB6013C22B922B3C6B7D306616468FAF5D3E5156248E946D0B474D27BFBE9DA5D5892CC5898DEAD776728C9612151EEE380AC47249C79AF8259C501669A2AEF714427B3435C8BA21B09A1EBE86BA0A5B5EB7C96DB6B1E750BE628D44AF9B72953012501C717CA602787A243018585AB3E100B1DC37DF0A645EECB0DBCA339CD4CB3716E06DEB5C0F93014DC116463D6E3E58784C703ECD47F3BE07CD8C3A03C63B3A7756C6980B594C221A0427FE2366BA3C15CEF9D80F428DDD797945A932AE0674BF3AACF7AB5426722480815A256D374D76BEE80A3AFB75234D72ED32CB71A29B5F4C6B5BB330FBFED834D38466DA5067AB111AD54A65C02B966028A652FFA6F805E73575D4E35E9194326FFB260B83751940317269A88395C1403E11C28F31482FF98FE95069A7DC83847DCDFA826BD571EA368347D6F194D186DE7CBFE11511006A7D92E0F5604FC378485B3C551BA0BCFEF3D8A131B2AD8B70DFB1B96B55CCDFBA23162228D365C3D7B5FA837D05B13797E715AEF5CC2380A0BAB45B23277973CCD942065237A314A1CE6D55334D46243AD5E0E4C898B8FC29695ACCE80791440B2DD1C429EB0C77CCDE47AEC84CE9FA879C62B56B85A09E9D6BF25FAF70F2E97C35A21C48CDC09D8A4C69693755681BC8093CDAF00E7AAD4A1991EA8996C336477E043068B204C37753C3E632EBB72F557BF673A6396781660ACF4C9137F14D329C54EF84BE96BE7DE214588FE1B8196523227AE4F6D39C6D89EEFE7181A68BAB52C7EB051D5278F5DA6979D6D40A550940CD38C39CA0F9885A0CD7368C99E65CEA2C9936C259335CE51784F05BF67A60248B0B680376D8ECFEAE5F51AE5D0C5F59D4CD4F6B7A944B363B39758CF836B95E869399F94030B87C04B157A56A971F8C10E892B0D9E7B82404A8342E54F1AF0504BB467D997041667D285233B950DF6F68CA7DA73BBD1ACD11326A829735A457E410F5490787568E8FCD6DF3B4CA576E2BCB63F9489316F9054E05F0FED134EA1B07FD11BF0A3BCBC3C63B51B71F1B16236853CC20C05FE221B45343531954CA1F2513D0E07AD77E9883B9A87537AE5891590A539C54102FD8DE8B9689D34F7C6EB1896578AD6F2DBCF02030EF37C0AD4BDC16A396C27BA98B8B7E50A7936FB8B4A8DF36E5F935A8FCA01518FE9BBA562F332AF88C04254DE76F5FAD566CCDD1081FCCA98DEFE076D4A3A7BB106319EA38D4BD756577D880526C26C56F0A4CA45C267B1785F32AECA8906F648477BA0D35CEB7A21029F88436519DB7DC880644082C33CA714EB8F077CE9E5EFB0ED2EF24024E764E54D08FF0ED653EE3A1BA47EE6B735667DE10844405F7E1B9E8719C90805996D0F5AF7B829BA981D2FDF66EAF58466CAA62707E991F6BFED0532B996E383CD9106A9F35D81DB9D85CA9A3B004C735E482DFD4CC5A6901702B88993C73062B76AEFA36E43DC84C7F2ECBE89A8F9686698F9F9F99AEEAD4464FDDFE259CE8A4444433478A31C483217982B62FB0504D29AD3624174B6FA9F58567A9C1EAC601E5FA98EBDDC0339FB4B7EA0957DF59AEF99EE9EB9ECD9EDD301007BED0793B0C82DA95885E4AEC1298D4F2B628A0B9FD433823FCF749DC7B83F636C9D2CC74A66D13A910DC9DE61C9BE0347A4822D466D9DA8A451FA81F2CEA7226456687F2CC4F3BD8FC0692D7CE7D42A51675C6EDA93B9C50C598C3E1460FB0A3B46B645F40F7A94136CB1003299F230801EF2FDC8E2692A9C5C7E9769071A40C0ABC77F1864494465255143CE56218AF0F5453EA1CBA5F2B5CEAA3D53DFB964A07F565414F325C55DA4B97ED51EF94699C277227BCAC026FFEC623E3996E91E942662B79CBB4D6817B0F971E2A5DF180CE3D43CEE5D9B0336F30F625B3D8657169C14B436F62A6E0F558006DDF71A0F4EBD7BCFEE0FBAB8EA99ADB7295CCD97C7D768FCA52DD578A3C24C991675ACD4AA38BF18D55E2E8F98B9D20C7ECE204BFE968C7ADBC4380DD6411E0C8F4372CCA61C855998BC2E544244B0DD2BABC9C1DECBEC893242F13F8257C503A270C459970DB8388FFF17DB1FCECDCCF3BA65AB54C08D539D19CA5E551558B0874E131001B49781471E825C2F79930CA14644DB085C51C580C60E2E9F0F57125B3744B2DB6F0348856DF7A6960E19AB48695DAC27A3E7DC00FE7F04FD2CFF3EB5286A3914DB760EE26C7EE02852C40FDB0B5B9E4E1C3AB570699E416DF5B5045E1FF95A1DE4A693F7ABB8625958359F3FECFAA2214D5EBE82782DBB6F7DAAAADED8486DE203ECD5AD7CEB9CCABD2D9E24FDCF18A083DC967DEB5DFACA5400E338831F76F65A9D0EF5AB260DE3DCA9D062E80F7050E33DEE5F3EC88F02E270D37ACF79749D9086347E1FFBEE622BD5466A60ED3B378BA2B207BD178C9F1B2EF1899829B91314315023370C039535AB66BB579A21E3FA7BA4889C88DEE0B97B8A2391140D82909E0482C125A3303B4E808C08360A954282ADA5BC59B118C42158EA4C4EE3C6276EF1523F6476982160D24DA193120255C66274EA34F181E033F747CDD4911D8C222F1A38605BB50787EABDDB915CBB6916CEDD5C7FF8568929B29B298E201C1EBDDEFE5E8B292493CEE4D28B8ABBA2CF10C5EDF0BFDB6B207DA55184FF73FC6A764897341BCC3F04BF8D37DB18C43E8B478A9D7A8A825745130A2ABA2DE420F6CFFB5FB946EA59BE40787307108E2AA86F8F69207ACC55C5F1DE1E657A7F8D32944859436C9E1AA0BB1846E0585923317FA539AB16B54F293ECC57619B04C68758CB5033BFAA4D993A7FD5B9F59482593FA97A30F6D5FDF48C18FDBA27552090C23C74EAA252EAF9E6208114A9DB422C767EB6BB9588B3DDB602969A9423C9CB848F8537C108D7F6651FC9AAA3A3F722B391DDE110B510576435E37A594009AFDB34B8A0FDF5BE546FD770B5E01813997CFFEAADD394F04D20832D8F6D37CDD5C5B9C2B74D74129E3FB186010240EA81B540B22725DF699DEC06151083FE15F5E872F6CA99C8EA3F17107D3D32EC5335A3A17D733DB648BC845C8037A339AEACFEB8FD55769E3332C3FFDD7E9BEDFA7C4DB85A32AB04BED5C87D68CD0BAE2EE48F091B2D5890FDFDD41877FC8C1139ED298BE5C21E3DB619E645F6749C074B3BEC599FC5CB1408238A6860511EA52BCEF1F4D456EA0B4E1ECEE64160C4886644698691A7E02BD20DE2CFDD5C4C84F027A6BB0CF25BB4C27E017FF1AD11EAF367C4ACD61ECCC289FEE7200BAC894F9EC083634BB7F02AF14FA55E7A6A2AC92DFE7C56ABEB45838AF272FD2D4D0467DC7BEA1C664FD96FCE60982B9257C50CFC146D101455BB78DCF9A32527BE9B896B47B63F6726DD9B0E90BC5754228D3E27AABBB8C67FAF82BB414343EAE8007AC7EC4E1F85ECA7B7DD238FC3E876CA103D8E0D28395365B9574C2C1EDEAACE9E5494DE2E42CACC24D2E51C3C2906DED76011FEA976551F960A80DA42117A9CE95FB8DAB75E2A322C37738D48F9703A318E3D897B942E472F5C2C4874E6F3A8502E15AC63485D14F99D82D7CD746BB25305C145B9DACAFF0C2C13146313CFBF0F4101A4ABD33002D3F76446933A7342609F6C44A602E951D2C17FA35B311C5DD4160230B6DC41BF4A7748A33CADC08BCF6E458F6193D51171C880FD828A7A1CAA90E453B632A0B61EDDD87B145B2A53BF022DD55DB6EEB879C8736782608D22E26D0E57017F9DFD439336505C4ED9E530035E1FAD6C89A8E7E5D3543FE459552E34C9FE405A671D21CB41D75FC69E4D1CA35BEBB5BB57BC5B5EA1689CBFC8857A9626EA9BE6988BEF13CAF528D4F7894E6003F879C3FB452F55E4E8D65630FCC06AAC575FECBD20ABC5AFB0F07702303777BEDDAC88E016FD76D7491734519ED4CB6C3B052F010D3DB08169EAE8CBF69EFC1D37E505B83C95B17650E9FAE13D3F9A99BC6DA12C54BF93D364C585D863D7C133F86181297E87D9EC3173B091112546FFC35C93B7D2E48EC90E74401681E2FA118B0C06742F5DF650258410E378A257A4DC07CB6DF94C4FFEE5A07764D80F604257394378DA23078EBA8D0412E3747985E91815E225515ADE84D09726DCB0DD39A6F457F23840CCE1F9F0BF441AC4DF8CD75425A5390736BF3B8BC99704F17F79D12EE7C30140EA1ECD5EF96C00865A4E77AC184C2AAE588EB76933125F8A40F35CBFDA75134738FF9050539195FE186EAE191155F4DC39AB93FB1A3A308A6F20E08F6A28F4F86789021D185459FC89C1A373ACBEAB3182B6E8DF7D7AD03B0CB8B4BD8E1FBFCBE24AD7CC877783128B1175EA753D3313DE7EAF19E4E7434F558984AB76D50DFFBC18B0EFD279B021D0CDB6B0CA35C481642B929C0F7BE4932ABA46379963E031C2302039CE973F611AAE95C97A6DF99BC11E1F5716D03FDC527F8701EACAC07697312EB3C1859F7372B97C3F583702A1BC210269EA7762F0F3E1BF6E1AB21A86EDEE008D1FB5CCC377F9DE89D123CE11DD91C40551BE6497BE4E798E49176D51334D631648E033703654184F1F213F6D60087578035DD440F4496D5335F3178038FDAB10912E1A4309D753360F58E11B91AF7160A7964EEE5DF44463234D57898A1798003CD11CE1692D1E523C324538BC90A08D7CA1A7D0FDE7E1AE1F837018299F6844919DAC422CFE125F673CC64FA253E6A3657118F26C399DE91339DF8B7C759F0281E79C9334060E95A4140A8BC104E7EF0EEC9DB891EA3C2E30D0482B83B66371C897548A32F5800339BADCA867DEC96B656331DFF75799D671CF98B409384070BC726A8A704D4240BC85102BB0BDFDC9945163D4371FE42311C4D785363C9849E69D5665985DCCC94778EFDB8ABB9B4954CEF0A182371E12D7F2E83D1699B9AC609AE75C07529884F2E61B5522CC2609F1FE1EFFD8F8E4CDF96DB830E2BFBF52CE1297A0B59D4773BEC99A670507709033CAFCD5EC77BF084BACE94ED6575E9D5D105CA35C59D4EEC40B679801206AD2AC8E88415D0C632AB5F40A9A7C1B7F2661AB977FEA2D1ECC0C49E24F9274FC4637655A457DB038F48046C07B15E138B64B0A0D0D76A23806D405F195F0F361766F207BB4C1CA206EA91E122223F2C20DEFE34303EB6B76A31A2C1FAE2EE202A268E46DE7EF18999E0DE868FD455222E3B420780395CA6ACD186ACD5B582E57120B677456E6863E67E6D8CE46288F0DE78767DC75F41E09DD4B446E2D708066DC3E917C5339BA5B80A67C119FA7A61176884DEBCF0A95A387BAAE013206D4D4086875FC3A0596256326D71BA795B48B4C8674F25488DF423ADB71E96F1D8267B223B75422F297FB7AA2749E5CC07EF9A40D2EC46E86F7BFCCA8EED1F100D7D7C523DC268F68987B4AE3795C489BEB29AD62FA36E5478B9E4A46BCBB6DD2DEF40EBD2A37EA2C6C9E44140BFA1541F679545CA4C004D694FF6BC642FBF6DC8F56ED9E9E4F154F765232FF1D8A36F7649D32A397ED29BC929D0C4F87607E9F8D519E42F189DF392CEC49DE8C9773913EF336C18B843E1DA9DF187D78323BC020BF86812B65EAAB5ECE27C60AC39BBB1A8471C330AF5F13E2B9B8EC252DF754B254A228428E25A0B67760EA9810D752BB4DAB6F86FE14C2D7D90F41169112CFA8CFD6E22656F8B5F408B1457236ECE20ADF8D37FD90149936C87F3B3419B967CCD3218502E2323875990FAB874B9B5714435AC008DFA2CA44E9C4589F6E5EF3B438910D8E013565AF8607906A6972FB210EA9830D6DA05DE0AF863847D1CE8D396A150A46CC65CDD6683DA93D9379DB121C3A5DFB886DC932E7D9F3CF1BCDDD2F4523D43495075B6CA51B6B36D345CAA3455415AEEDC25D4E599F5E17C262E1D3648C735E1D107621E94BCDE5AC22D235F1C6320DA141ABB871F1550B3934A862F11759B57BBC697751B6F0998ADF3FBEAA875C7AD5D2EACE31FF0A7697C7E8D9D548B4EBD17CCD4E3107E08C1FEDB78C77ECC3121E8DBBA5F33B32490A9A8F32430077325BB79B7DA97AF89188EE097438051116FA2BDA5C8B10937CFA66C93999696A1951FF819903CD4DF8DA46C696A82CAFC3D428ABBD19D931ED40AF3AE763D2D85F74B190E7C8F53F95E8F425BCFDE42C255E2D0C71C8EECAF2D75A8E436326FD0003C47AC4520DE0D09A649BE4CC0937DEF29E1E50D2DC13FF85F2F5B9C5D9FA84E8F1C635B31EC36C7DDF5DDCDE40E5CD04542D6DABD5F1C9FA3DE3256A6EBFF8317A25B1D64C231FFBBA26C4A61E2D6918501885D23BFF0EA3AC71D62ECF16A4A403EB0BAA0E2D2CD9FF99AAE4A5767C1401E4811363FC2C85DFB003690D0F95550B7A1C8A316B0CE12BF9CE6884EE63AFDAE32E647BB01E20754D050B0E48D3BE022FC3091646F720590CC3821CA1C2E4CB11B1D0CDA784CE7332D1289B55EDFF7BEB1A57C32EB18CB3EC0C008E91635675A060FC484FA91C878637D7D3AB1C550D52137FF848852C0DFA1066B40C54BB1AB4D3A7BAFB419F6B0290485ABF86D442C01CD34C7E0B49482BE799EF042F17CE82975A7F6F251A256FFDF381CD47E5840F6AE324134DB21F5306D005770F59062205A2A50AD3BDA340F68A301A9C5EFBED00EE6D2549D4353C65531CC85B2BFA2E1E2E1C43D294EDC8187DE772FE84A613A860930987245021E677AFB175BBBEEE0D2E9F4272945DA3E7E4599A062BB4151482841A0A075CBD708EE83038C5BC6217FD9EA299BAA62C8A9D00D3D1C0B0DEA7D887321DC6DBABD1390D18C0D840E8C83B6AC6FA6BFD9BB491D0D5A32DE67DA7A90879BE849D72B4991E87566ACE5B72B401C83E6887B05245B6BB398034EFB053838F33B39CD9F3992F821C4FE17B5D1A65E80DA6D12B384C3D5B5E810BD41B2AC747D61B75E89C1F6F0F93B00C8FA1054C4564501A879B59AAB99C38E962A8B34218DF8270996FCA48282E6C84E2F5D99447E3B4975D43A6CA56B4D5A2E4379D7C1892F269354D2FF9FBBD6E2E65B05F8F4F1D20F024DBE51B38C7CDC969C605865CD245328518B168E3D973426EEF82247E3F68E9CDFA4E6DD58771E6B613D36EFFDD1DE7E4DDCEB806EEEA6339BA92BAAE83DD3D34F5536ACA2A0043D0B857DE4CACFD019A30A85B6CADEF21651887E5CB52AF0DE2101BFCDEA8288D292B55E6004F7BC1906E0D5D81CF4D40F23212E2A7297F26AE581DC87E9D7FA79E2A1AB9EED15377FB3F0F4A794D560FD88A8A5E5FB6B733E544C763C776F0AFB886AAE7CF25DB8C8072A95E6D546B65BBE53F6F4D282E3901D9DFCA6DD3EA949D7CAEE4B311E517F9D7768DFFC91DB51F2537B21B8E2C576B5DF9A43DC553F6F099277B197A8AF3975AED697F99970B8E0D9FB1DADB3DB4F7B86F4E158C62D730F61786D49BC2AED7129D5933141FCA9C1F30A0AC84FD082FFC16EC29621624A4107D9F54332ABEAE4C46C7E35DA10EA488A02BB116F7AE856BB9FF5A70EB1DEA70A6E412B4534C3AE1B794337273E9EB615D148FF0954AF49043A78F559065D07A4A57379C7FF1AD302C4651FC4EC9134954FAD6CB9824C7EE7092B5F07C57381980824B8723406C33E028256D297522F9A80BBCD87F60FC85EE5ADCDC359D5841A38B6171C2CB4501C3463C94BAA6394D6EEB8DD4A8EB94F1F40E5268422F8A1CBCE00362C291E535D055B40452F09430B32F0BBFAA1521B6FE2403A8011567775A8F855EE6FC7C6AAB37E9DA92931607A6637DB996E4AC423EEA5F3F0C807DCA3046A768F84AA430D89294466760A15D5310288EDF97CDF1F88D998B2D550D3F8E413B33E07917DEE25D5154D694DFC8658C8419CFFC0B6B8A87D20019869E39F77AEB372906E9D729F88AEB034889DA9DA301BB8F04BA6988644ACA4041C76D4854AD606F6D7B7748031E7A6593DFC5522251E0F3D69EA4DB5A94A48E31EA4862E07ED30DDC0CEF93F5921DA995C41D08C8FC3A8A3A5DC737BB3C7C4D0F7CEA10C80039A0E89E4E6CDC1B419DC65007C6E1A3FB1C0B10732A2FBBAC2A69CBAF472FD4099D8B0EBCB41835AABD77E6E35756D608BEC409F4D1ADB4BF9552569276C8C984B9A76E9CFA62BF260FE220EEDF50FE70FC327810A49DB0FC27F91F733E358CDE56C64445D7C24B26D4BE8282A9ECA8B4C594D80397204AFDFD366F358983D48274CACB8815B415C4461F30FF8BAE32973EA90702C7F1A9224E5A09ED96813605AE1E30DC73D75DCC97900540429947F71405C6BF9982A0A5A74F5F7380AD644B5F7388D3A5469CF568908568A74061ADCD8A9AFADC858936E1D62310DCC65D2D08AC80B4370571AF00A34512B9827BCA502C39DDDA6CF7D037CFE916F59D98ADA34EFB130AC1D9F7586567D465B0F6CAFD18AE6564006BF3CF8B76110CDA146877BAC3B04D78D30E91ADDE4650C76BADD0E5F10A06006876FF488BEDC06B9536ABC89BD15ED7A0FE22B475DC776B3C5B79467C9210C031038C2297FE6705B3077A45B19D12E4F45D7811CA3713E4999736F2E383730F8C6D55AEB64335290FFCEB89B100F2634E6CC9FFA1AD2D86B23275DD2766F2AE913B56A4006141BE5D29BEF7BDC6270F646E59E622143AE301561FF8019242CEE4A94FD81056D1A842FC13EC803EDCC22A876F7A25D747E113670AD20984BA61064F269A884186C3D88FCD69F55E5A1C28298CCBF3590E1B33D829A72AAA380066093ADA5B04EBA74362C333F28BB94D1E357C3185107A3129719F63F8DA269BC3BFF5BE9B6841946B01EC7D8A279CD34C22714145FBB05BB7C642ACA946B92FD05D6B8F6EF57F8F86B23D457C21F76C2E48BAB1F9F6F92F4F54A40AF7D8569857589F8193BB1BF6E47B483F1AFFB06BC13A74FFDF10887FEEFF4A8AEC540ADEF148453C8DC896933889D27276D81E89DF905EF2A747D0AC852D5A2A4E5470C6FDCF0739799FFC202D1C47BFBD0DAD391988EF6D1AF89E0881CECC89E8B3AF80499F8014013802BEFD79EB3550626B51A742EDFDE4CA567DD318618C5EF9AA0841A812185F447BF776C42771666110F34B1B7392CBE1286BA7EF687D3F898324EB51967155A66D1AD5A9DF1D260E6D3B95A105D21E9569D81977CECC6F41A155D15D7FC39CA69450FD822825C931D376ABC7BEE0DF54726B253327EA075AACFDDFA84EF97509034481E53690F08F0B3151C6271C3F810E2046F4DC9FFB1636242318B4D473254CC2E3FE61DD84C95FF1C313003D8ED006848CC22EC1DBE742F3C2BB6A4080DE546203A5FC46158AE275B6B8874E09F8EF9D5935B2C7975078E0448768773F16BA5A611A367E6D6FCA3F89B61254D7877B3B32A9573B38B57C3A2469A5DFCA7C2BD90D5ED585241236A070EB8D139A9D49FA5732E36AEFC7B9369F6A9094103B2B06D9BCF21181C26E16044702E1FC1BA4B4FDC61AF57305860F70574792283AE773DD792F3F5247B07228666075C7299DE6FCC8DF07BF088008EC44593244967C74BCCA1B89F2917DDCCDC9FE030E7243C9899C28A4BFA44DE8F321D0C0147E4C26697EE81AF31773256D8EABFCE1833ABD047DB080CCD5E3A4E50EA175C6DB6B69B6EF86392F58374A2CE57AA34922E7A4A7979B8FE80315EFB817632A51A01AD821F51FD927E244AFFD9883D2B5ABBC48290325D1B39D5ED6C8AE1B73F834D2B0C8304F057B10A7CD695F1D46D9DE8DD38B6B5F3450D31870FA8AF9CFBFADFF0AEF6DB1437F37B3884776A4CC0E5951B27DDB11F73FC21E7973BE3D2EA8EF440E1B2B903B90FBAEAD629F066F4C8C2F37B992BEF3BC1A268F99424F1DE526274DE5E1483D811B552CCEDE116641B7BBB2DC2254D02D29FF63591146E6286D7B84054827083EFB5A0E72EC2DAB8D8FA0D038678B50AA3C960CF98738DB19C818EC79AEF5E287E42A57730F0CB336E8FA81FC60BE3159E532FB3ABEFC6952CD0D7FAF549488119D30E6A8D545ED37C0BBE5E08BA82747B8310E27078FC8DAC32CC8EC3483E2DEEB1D9487F5E99AF35A02BA77C72C7F95F9B4233763632F21C8DC926049373A8B33BD1D0B3E10FBDB78619A26B191A7659D02236F1F168BF818C2A8E1C50364F4397C197E820C981D23325DEF6B37F471CE5773AE3B63F74D2BAF17C63E1F1DD650F56EA60375BD00A05ED30663A7A72098E6F0D2E9B5F998121CE44F1D487BF648B19702689D58CF3A5D54250C195A1FFE251EAA055697E807C7435C34F76E0483EF2FCDC79555B7810639719DF16F657929367B5CFFD5687F5EA7BE44D9C563CEF2267B7ED33934A06BA9EACF1736AF7588360A5B3D06BA5AAE90F0C9F6132AF0F888D4A0E4EDAF2391A853AA2007104F71A46804C65C57D6D7506C726CC658CF441AD627862129E03AC0A784DD81AB0B036D905ED27F0BCEA05AD21EDDE9F4393D313BDB1213BD01F34A73C21AF821A96F4A6C510F85F07FE5E84B33232D3ABE92C27D0F3B1A557FBE9FD4D2FEF1A6EB9DF53C0898870BBA4066F567837B91D82D62C3C1E3BFAEAB52F4E80B3030E6EB5FDEAEC5055821569460CED9C5A864969B1513D5DCF6BA3CBA3160C9DD901B0F30BB1FF8123CED314890C8ADFC58ECB3CEB5AB5B4027966FD6B0F1E29979E75D0EBB32A25C335C466063FD735680FDBC23FA33C4FD29CA635D6C3B6E835DA546142F3EEA1500ADF27AA8750A8AF3CC022F75403EB00B8C4DA547A30A25D6EEE56E887722931D316428F3C089676FBB00765135623303DE8B51C2074674D6E64B21EC6A4604426354E773429E96DE0FAC9E27D11C1200C1D8CE7B74F67228D76B825757771C4928577D4772F4EC9D06C6B8797F4C3",
        .sig = "38F090E96F70C349B2F7F5222ECCED39FBC011D899838B6385C547C489DB07F7E16C67FF2A72B3AD6ACD4FE29B265930C2917608DE48576D9D2B06BB314CB1978FED83802C953949192E91809F10231643F29AF9F24B0919C2BAE2A1B05B51EE4106E0C640211A4A0B2D7FF26ED68A7C03D8F2EBA9F6A815B81DBDAE108829E8C8BBBAEB5F9C54CE944EDA9F37EEA8D77A8EA5C5932E19F0ED53DCFC17E0D4C9A09F7AF37BDE11311DD7BE9834DBDD3319E1F2DD4F402A6A18318353066F0EDFDD2CD1C6A068BEB99E58E5A974435B598F71DACD3C5060E840FE0245D4C1B4B216EDB1A182CB4D8EE4B87D46556766CD189A6FE5D0F4000EEE20C5017BD568AE4C280084F785EA40E4BB64EB6DECDDEDB795C79E36D0C4E032E0314DD92155593F3175A49B3A4D66FD6380AECE85EC06512B6A3D28C8A132B0C9571BD8477468CB0D1F5F2D30076F1FEE8E02D859275F935D06AFE92956603D173D9022D2F1C9FD66E58EB712676BBB9585395EFE1E70BB62CB0515F25639B60183518AF6C80B0B96061E07D2B8F5EB9F88225258F82CC1D6A165CBADEB7C1DD015B9D4A09E0352AF9934002247CA179F5629805D736F531D4453BD9F629EDC5CD7905FE3C010B39B572D52938E62F1341A34A9EE7BDF348B84FEE3C24EC1D13E755377CB6404A32492787967D8DB5C05E42D07843412D1CB9CCBCB6A36DEFDC69DAE7F0012DD1ABC4345566AFACCDD6DAA7E5C764E87F14B636E7292F5A61D33D9F175F31828A8A0374B16C9214CFE9E4D543BC1E036C05FDA1E99F595E3E67E1EC9D6126618F2CA820381B9E3A73D85A2400A226E52508E6D8C9D2433CC30A482F84F6CF13345387693B15DCC704A9917348E0BA630F7268B819572DAFAFC0E81EE012E44F304D7EF11CA27B14E32DCD4628BB1AFB620E48538AED6296FC0FFBF7ACBA790A7559B3F232CC69F506201A85C5740D4106477496028663F215ACDB13AEDC7A20CDBD25788C3E9234A17CA60A04EF044877C66F2CA58432FE115C83A8430C9CD7D28FAA551A8A7971F6CF2EBE686260D08537ACDCD93621F883AEA5E020221CC6493BADEAFEA26B2AE3185707D9764FAEE3487D2F9DF9AD5446661A0A46B4F7257FF8CB3DAF7C86482278678388AACF10EE5E3DAC609BC1952F8264CFB013A129A522696E62D3466934F05CB1F0EBB14270AC48E0019E98AE58119A384C81E1BED12C3F49EA650029D4A3C04E093F9617346DABE1F9A71D629BFE2A67812D6441557BA9E055878F81E26136A0A475443D03DE5FE34D5027D380339FDBAF69A0F78A112C8E2C085C37101E424E35E4DA645D03671BF030253384364BCF99F27135671071ACA1BD7D402FF513BE24407E400495C2D3635E320BA747026EF4510B3BBE22B3266CFFCC42A587BB8DAF9325EDED5CBFF9213F5616D935C2C81D65BE85662D47A63BC71A97FECC21DA89EFACC389944F0CA94604A6E102E57B7D2C567EE185B1EA07F2752EB85D2B2B90056FCCE7D0FA40DB9D189C88449C50CE78884594081C0E0FB835EB919CD9995FEBCDB7177A84213809CF107DEA6EC7769F24AC4C7047EF7BC5E365A3DA7A074B8CFB5FED85539AE397CF7EBC4B55A99A9A3AF14926C59B487F6CB66170800B9A5FAF484B536B608F4C1AE5B7B6CD7AD09003956300F36D040A7CCE76F2D50F63ED9CB7158FC058ECBECEAAD7A02FDB6EE5703D451E4C832A02972934FC34DA1C1F6680DA3B15B1877B4CB25E05DCD32EDB00269042384EEA16C758FE1B32121CE692C5E327C2B93E64AF2770C2FE2B88DACC96525FB46A7EDE1D43F2ED9CC0122934514B95C08F1C3937FB8DAF833A7C2E32A26600F6C2A69667F60A7B4B81115FD32AE3577900E8B11F17DA57CD4FDDF19DC174427D05DE53D276F755AA8EDEBE83AB4A82D58349C6963F052DCE606A8A06075D91BEF2F16CA0178899FE4F3E7DCCC7B0854A31D95E1AB4019B834EB3004C4B7A63DF73C9F7CB0CE2E9F15C4DBCCF206F93837A20211EDCA3DCF5794B77579FB943C9584F19B48C14790384856C4F8A6AB8783C9FEC7FDD53EBD536DDF2EC5090F160CE1A72E346303CF647D1BCD8B8928EFDA579EB69CAFF51B58A77F48345D4BBAD29163DC8D4B9B566C2744DDB4C771BD38CEBA46DFD494655AB66D075F12636515A2688F23B39E92B63219A599CD1D15E66354C218BFC3EADA673653812BF3B2E5D760647BFB2C65EF64363331FA54609C3291F3285C3E76A5EA81E02080B2055BCD4687ED8DF984E1FF9859B1B85085732C376DC9060B1787C3A778E75B60DF98D86691D626BA71E50B37AB9D4BF96C4195A6866859B6EAB710A2F28E62908B0EDCE20F3EC5487B30BEBDA898A7BA70878332940FB4DB2E6CD8D248D6E0BAFA91FE51CD6C9057FED8785E7E5631424487A8E8CFDD5EE78A3C8C8FC882DA1E27EFE647EB0529553EE371B3E3AF6E5135CAB410F1444A1153B87BC8AE91782115CE446C4E742D539710D2547C8701AA5F865D095B0299B2AFCC22A35CBE23FC813175EBB281CEED1233CAB85005A7DED484E5AA95C72DCAF3BDA6C0AA3FE82725ED770B82DBB5F79B66A17CA41CC7B07D9AC34BA7C8717035F40F3CB3580B1DE12312B149EAA52240EF945A6EA788DC3BA82ED2881710F1FDCEBB1D6A50CC0C28018A2837DDBDB19D893305BC2DC5DBD2E1B72DD2D372F3884F794B49330855351468243EBCD524406A04258961A0046B97F2FA0A4E575F46C823D92368C63D80B3976D6DD8A109CDB54316477116D54C3FEEF3B19E4E934D684BB18DDE1B396FD056733364B24A2822B7F1A49DDB2AE19213E4E22B4D00CEEE93DB74FB1B2230CEF71A2BE44868B0BB0B905DB49A0B19B55942B2603E46E3B7D34AA3E5877E64A5D4EC487A56C3DAFF772176267241CDC520EFDB08919595D67C619121F99113CCF5C26E000DEF5D4202261FAD2481CC8A5FD73889AB3A565839B925883BCF44B404A2C6EA39327AAB30A0E9407BF7DF38538B931C16589ECB928623C44191EC1CC8CFD4069C6726424F2DBC11C0D81632C23CA7676256909917CA01F33070489842CD4FA05BBDCD3CE84223918119D3075BD69D9867A790076A3A31E536A712A75542DB482CB877B9DB87F04901C0B5BDBC65BCAC6C5CD7C1394AA497AC6845F850BCF6192F0060F46E2FA343A57B2CF025B834C9D1B0406FF538B2A2153AF183F15D19ECDF1BC9B77973F5C28900D0AE94BD0C1F178D2D63F4662D2DECF1CDADA12237C0465F502E4066689B3617F48BD9D15974430E173153E3FC701B3FFD7AB15301E7D4BC0CAC3ED9B14C188DA2EED61F9551EA3E92D3E0F9D501BEF5E6A9F5B128A49F0C61E596DDF1EBBC500FF011BFE2FD9EF86ECCA41EF3C0FA68EDE6A13BA13C37B96725C68B053ABD5C33B650BFB15C6FE1EDB015CB652269453E4182F8E1B973FDA6CB5471A092F5A30D4AA27787E7016936743FB561A0EF97480885EB9D83845E709A1B21E2A68AD5EA5F9575AA6E47D0E256A2AE0FDC35F0F85BAD7E8B79A82870D8664FEE656EB77818D94B89FD040963304A72885052A2A1E26DF98A8D2B3A9B51EBB126136331033C4D1E4D90593C113D8D0F373F8E1ADC38A6CBBD13C19432A975DA09FB8BEF48B7E765DCA9ACB68B4AEB56654DEA51127482166D0FEA00DDACC02ABEB9CE08BA2E88563EF6B77FF1C1D2CA73B3741C24C4B17EDF628E7A0F345352DEDBF68D0CAEB1483F199D625F111C47583506E2B5D2B7B1616C4C8828DF9EAA9C29C51FB6E9C9143927080C7209D4A77F153780F32EE812F2C48D6E02BE9CAA31A0F41465B2FE31D465461D22B5640765E3942CC8571A1F181F1989ECCA3697119E1D4EA7AC3FEE3EAF8F08675625FE32F0A15B848D54940B4E5DBBBC51082F425B927CAD8975E28FC953EAB8874060BFFD1E85D81521549447E50A981AF8FEE3ED288D51DC352ACA1CFBE33466472FE9F8E99B25D134F5880E0BA6695DB585608F3BBD322649FFAB54BEF5BC5757B2B6CAAADD6FF0BB303089FF8844CD5646F4B48A796AC80E908AC3D6467281DF56A5FD5748059F9162B1299AC64F9EF2F3BC528692E38EF62D7693E1DE24E8C5FE44CC592261C4A2366E5330090296FBDCCE7CE37D4A4091A3E4BC309B7ED5C3D5A41DF55B8D6C40F170C78E1C31929116388E75B116588CCBAABD7DBC42B2CC926964DA61DC83FDAB47913D781437FA8556BDC2C5A366699158C72F7C1E48EF4F0267729CD079D1C58F10C119D455F701E115470B1CFA37E70699BCD5D9755D9C6E0190B8E7D08277153D83CECA5D6231843D7A87C8F58A08C379401D521DABB22A0DB46CA58D45B742C2DDC0260577F2A9AE4C30FAE2C40A899D8307A7E608939A56CC69BC8F7557C8B397EA6141369B157160FAAE6988D6EC508A73E454CE33D614DFC3AFE8A374F6E2B5C6DA95CD1FDA7D594940F3C03377CD330DE5A9AB9EF9410010278D896E52912BD4D9E1D949F95087D0F0D204E5EEFD41F392FC1E6ACE54F869B28A872FC0245F67196E316406257F338D7A21603A49BC6FA3C544C1CCC8CBFB53E62C95E48F8327576CB7E17EEFF44C4EFCE4D86EAF16FF181ABB3E5CCEE978094083BB66AC257B12C6A01036856A5720291DD4415EEB4EAD88D861C444A89D0801BDD9D67C30A7163AE2B606C7C9A66BE27ADA79278B045CC33612C3B8D321AA5F3DDACA21084BC8E9B301965247B67A052C89939A614664AAE0AC40C98CD49A1D50C2D479675265CD4E2603A5C61BF9A5D1CE2F50BEE66CE5C243A97F24A6FF442F5EC1F01EDC0078D3009A474559B2DC576F82AEC6C078C25ED96987702A2AB3F8790620E50CA5CE5A99447F4AA5B681E79485A1A0B31EB8E4931167BE532F83402347075AF716B0C3D62814FDF48194A0A5D698127C7763CDCA9E566855CC7DB4D53877BE297A999F3E9D1FFC5825F0223A5F4733BF3E190F33BC19DB713F5B6FA71D06668415A041D8D716E1C33F127BD41BD63C0E70DEEC1F0EBBE578D60C96511EEC10250DD6E92834EB4F07DA57EB985F61473A8E2426355595C938B6F11A5C18FBC9EB14BD34B4BC965138171C81589F565AC4EDAB623E24B9C5219385D8D2FC3D7D7BFFE830E48BE5FA8A7846A19668FA7C2F92856ABCA3110DA718252E00F6BA7723BCE9B45C89B9123E5B1A85085D44E7587918F769CA156D92E068CFBF1F572DF15EF49098888592D10FE33A242E70E899959E9C52AA18F2214E0628D44C4DDF32B22EDA8CC88A4D5A5B68422926B67473E5516BC36959A230FD9CBC50E80C4C06FE5443F9DD4FC8F9B2D7EE2CF93D5C6285685DA5FD28D4A124145A63869902CF9E255286B5CC1B5AB3CEDD0B9B7B16663919737AA9D4F98F50AF37CD0B7529566BD84DF1F26A077364B654E9E1EB0B83DB186FDA8A19CBB90A79E32F329F58646C66B63BA28D505CEC735A098C784B113155C924818ABB449B0DE2F97DAB80F266402AEAA921AD626538FA40A0B4F8D6C021DAD976FE94326AF49A1476626BAAB11BB166173837A88AAF292FD5A4AB9EDC971A3133FBB6BC3ADF9725B38E8072F9D42D92EAA847E514ED12C003CFFC1E52F47380A66694A6DB3B5DA4F05A128B4100C6E5E8948402165CBD2C363C440FE225DC7321CCE2FCA9E4D7FA1667D3DCC16BBB2C37058E261B98EE6BA8830B0F9E8617729ADCD2CB13F2DCB6C600A5B17B28492041A6F2A2E4F1767F5B18458C2BACF45C1AF60C7215D8EA012B8350A1F93D2F49564C1B354358998253099C10BDC489DEE8456A66D1E0DD7589275984E0D2A5001C88760B70B4DE152DC6A3EBEA18A73009E99A5653A5FA8501C8A473D49AAF3E00C63227FFC315B31C4617B8B052F4806301C78177CD888058C0DF08D60F09F90FD54F09B453C3F7217A8F7F7928B669DBD8363BE56AA18547E54007B4D30F5AA122555EE5318EEAA96BBD9A5ECE5E35EBC5693D8ABFE7085A07E375F3D05273B8D3897F08CF722BADB78D09CCFB10787219BEE2B93795DEBC7CE1F9DA5098C0F0675BC57A851C99F49F3E1BDADF6C547CBF265591D171EC5BAA0C290ADC2DFA44C89FABA4A39BF47AA16B06BD66C2FE9958249E10AC7FEBB4E554131E948DEED24587062FBBA41E6CF0E1E991324BFECDBECE7808919024800D36682FB3A549EFF42954F79222F35D26B8AB6FB7B48D1591DE082F16EC06237C7963B4458A32F312AEBB2956B163BB9E3D049887D426690D6EE668F061BEF185AF0967A031D0084F919D4C837716545C50932145A412AF384FF08A88132F298CBF58C4661D235D87D3FF8469492A1A0B99F44609E62540F2EA3392843BDFFCDD68AE61BE06415F926E34C969686748DC005117F87286926DBE146A4218DC18512702C05BCDFC964470565396180305A72E3902C746F123FE5579D4E30DCA4EA9D18E7584F92DC50653D7E9328306C5C9190139EDF51723FCBD1ABFED644846F3D156B9DB3BC3A796843167DC06DA16F7DA4153C160D71C56ACA3612DA2FE9F4FF4C6CB00993D8FB2D63ACE78B86496AE111F8F32F1111FBA49B9BB04E1C8324E204780581D219D7554E54E5A1AF6CB1CD3F5A0950151DE8F12F35ABD7B3C633F412BC99233680AE1CF27AB56B6B30A45941711BED75980471EDE1C507EE35C710F04987CC22ABACAE9CF316F0D8F2486FAEE98EBC522EDDDF636D06C7EF1CD315A56CCC68A31ACE6E426E021DB64CE9FA529A70ACD9F1F7A0BFCDE17B53ACFDC587B7671A93A76CD4BED047BC6354B760526C3146759D3BF9928E331ADDABF3E9FE344698662E05DC279C17260EC19BBC5B5291405E2396BB303BD990E1F012A8DCB1BA80E828CE3C3E2359BFF84A864A2F919AB16275CCC47F1977C22BDC7B43195DA0AAF0F0571ECA573FE8342DC711365BF75313946D9E5FC4B66E47AC8BE8D4389B19A95DC74AD61A076F4AF4338922D2A65809B3C0A1C9A50F850C7D28BC8C786128A5AC2E7E8302BEEDE6896C3B30D56E9F5774D19953858A2A437BF07273FE086DFFC120D48D9F7B522F046EFEA62AAA78EB1CD6E1A4D5C54815DD3404A8560890DCF2A2D272F9C5973E3E3D04969DC415B9AFD1E908BB135135146FD93C906E2AC05A67AA4732ECD49AB449F87F8D5B84A5C2F2F6B19B20D1681DB75AA4E7C327D9075490D72C4582451281D164C5C0392701AA6940CF26B81FDE21C0FC6B560A047B46641858B08A3934188D08605FF27D201022BFCDA5E5CE5A8265566DA0641245B86B5D2BD412733ED3B906005935DD0A8A6C6142F5502A6BF5432FC663486356CF221B34C22850A4ED6D3BD649E1A5DEBD314709656CBC4659FF3E095B589F73D84767E3D3AD2FF112DD0BBA217A46A52178312DA2B0B125D74C0C75C481AB819482835227A1EB2E7E720DA94C790355A1DD4A10467401A126D57618B2C6E9EDD785C3E37D218C5D52CFC50DC13977A8083BC6E529AF2DD49700420DD22C99E388D1DD70848443FB6818035D417FF815988765FCE05EEE33D6DE0D56155BE38A6E9AF293D3E17E2132477ED4C16E34B3BAB672C667F8E75F3AB6D85B1F2E3D791CA2782F473079474E7F58E23A163B73CB78964868FB7EB43D775B10FA071575D7CFF205E1999BA7433F7CE330553C03320425CE9EE8D7668928ABCB4E63991D966BD478C6DAB53202E912E50D1822DA47323CD51DC85A916D3E548A823ED4DE8BB911D3E0F0E59D74B7756054C91F10603B88F3DBE4A1456ABDAB3586F4315C1746F7736513CA70B18CCC3A7F157D66340B3A2140BE038DF5CFB90DCA603B3D151FACE585BF321D47B0FC4D73286F90703FD01C91B06D7C55F10B9901ADA34074F2935885FD304A651988DCE2BC3143BEC56C5D2F4937A10ADF5545FE9B9B5FA354EA8599ADE5FFD86BB4B27F6F20C02693576690AF2EA18091811DFCD31669B0013257FAC58ABBBC677F93A2CD69D1EF68D3088322FB37D4BD2989E4EA467A9119E75B423999E93B461324FBBF260C0E352F5E2AD8FA344C23015B0AEF5D436313BC6A0C2A3556D5C9458605AA3D5A23AA45B8EB75996D1631187AC8E8F9D8C7C32459C5EDB95258BCFFBA4BE45002FF28D627CEDD9D7318160BD96F6D43D544C859D51AC224D17C1E9D3EF72EA914ED718189BC90BC051CF09A4D9D5AF393D3EB6EA4F5644211913CEF6E935B8088DFB918EA76CD5A5BD4118B63B2B815AF5C2114C61177F59074E620F352C1D6BA882564B7CD607CFB6EF1078E7AAF0B58B581D7C3CCB9A4ED61F098ADF54B9118768FEF4470C8EA98D3A0353BC507B66558F7FFFCB7F29DD262055F233548C6DCD88B74D2A0662F20800AF1ED2DC58ACFDDE5A0B52C1CDB07FD97084CD9DBCA9298BCBA7A1F8911E1A3F1DD3BB27AA07F7B2C845191459809F0BD41159AF8EEE0011456923FC582C59A0AB292F6D602836A547ED643604434729FEA2B3885C637137B72AD0ACF4BB7E840BF046979146294CB7A32085D98813622F54C315B66D81F39F40985E5C2C62D608323385A55B97A1A92543893DF3FB3BE9853222372BB6F8A58122778970745FF9F00A8BA1721E16A02B744C39720E228A220ED7A20FF3E43577F84E6821069CA4454219C15A4E18CE30FF150EAB6D1BD3F0C3321D9AD6901DF7DF78A3F04EBEB72A779E8739B482E0EBF19EE92A77D4F1F7B60E667639ED50BF66800C70932400641AC6D9266A050CEEEFD896C133FCE307CA5D893D5F58A459661DE15DE42D2183ACC8CAF8C063876A1773EEBA178FF389640777E21BB8113A2F883C335631F69D4B0A9BD9D23CA021D01515A266E11B282649F7FBA0B4D86431E269189997CF518A7B223E4D367E843B175B10D459292CFCA91BFE239B3458DADA6F695D16F92D1815D5E80233F0C134EECBD66FE39303568D87F87BB421A7B1701FF6C60194E63B021FD368E3D2219A528C68E956BBACF423BCF5F22A827EEC3CB9D14C4CD415460812B84A91A37919AF0F9C45670081394D209374B461EAC561EABEF8524C2905A245F35D771DFF96DB98981D2CF1ADEAF51B15C01FCD213CE8C06AF68BD195994CFB69B459B7FF09A4F46991FBD2CB6037ACAF62AE57CDDA816CCEEE91F953E3409745D7AA57C03958B36E2ACF029ED359E9AE338D4A3FE7888DC1E84BB0A1EF8B1FC0C4CDAD8B176AA11B181142A8D6C55B2890908932C786086E42FF00B3AEBB7B6385E7510723CBB07F5E808B8EDACFD33009770DDD2A6B3A96DA93B36FAE37B4AC56BF47344CB2A709222E9879E59CE355B8E1B3113C2DDAB6B23386316F4E48C8024AE5FA155BBB93FDAA73240743B6A08A32D17B77E45B0DA43B38CA47AA1F56F6722546640A44F207F249BE9F9C7BADF501307D377E5DF7002A4C8487112FA552C08BBC2BBEC4500BC9B98AF1A417BAD389F82680C40750311A25EE015D33A3B3A44B2C60D531A9AF8844181B32A24FAAE10A4534E7CBD21A706AC8600C2B3D872F0CE46573EA16B0EAD4197B3D6B8E1449880163F31BB4A6826E0AE1A42806583FA8FA7D8BCA379F850B4F2A34348C248889E9AE8901228B4E11938A56BB3CDB41265BF03EA8E9883896A4E07B565EDF69221B3661AC2D41DE055DFDCC7C48CF7E1105E5FE59D5E4561E3A225C9BCE4E7D1B4CA91E3D00E6DB85ADB842975B1197F3C22DC7AE98AEB9B505C78EEB526B29473100CF01925B2A561EDB10209186171112C48F02D6D4E9945A93401B7DDEB06930D565F7AE3D30AA284E9562B858A3A5AEDCAD7740ECD19EBFFE4801C419928B74406C232CAE9B8FF1ED1E9950E956A901C26BCAD903E02245352B95DD586414DCF692CA33D302A37744001AF0465853FC76564E9884D13B60047102F4087D447FD7A59834B66ABAC991A0E4C5B697865DDC98E27DD6E2A2C8456B5D480186668A1B8435AC2E75E35B137F80D37A8E8BABDE0D121F453BE1F4B46F4D3647AE37EAF7B37AD34BCF74118C449250F9269066223CF995C9F1773619217B5BBADDFCA61F5ABBCA86A669F9D5229F941B5E55B216470F8B75EB34320AC929DBB5F6B4BE38F367F7CB090AE85966FCB6202EA50164B75C592056BCB50879ED2F68A9B8D859DC1A297932AA861454D6EE3C0C522FA095980ED53A8D766AE0A0AB4168DC552A5F7F48C08DE36FE01E443E697AAE13F3010060523E037AE20468D50C003BD87BCEF48D2A4A4F1DB6C92D170F67B544C9A0624FFA63FE49ED6E37418F927C004BFB4BC1CBA39437BC0699C1228CD7F16670D10C74649F5E26C126CC819B65D7FEE2917BEB6ED160455E4F47E71D0E8477A2746CE981AF889628D0268D5B3ED4C9D632C0A42D8C38AE428AC6B715785755B90C4816E1325FBD862A3EF322FE8AA93507C13935CA8BBF068D135989A11FAE9E98A4494154E3D1AE8CB6A97BEF3D179B43C815A513D96CE4BC9B0F47C5C55BF0D6573D2A36040B6C66DB9BD4BEBB6226363944C8CF0B8F989BC56A67C43FB700B850BF4ED52857E216A4604B957048DB6C79E6BF199592D3167100925E94051399F2DB38639C05BFD3EEF8C5B985F975A8FABE32909537239421E81BCD4198D1E51062355BE0DD16C5025DE43944CE46E528801753474624155BD98C29451E2A0BF51E2CC099D80F76284A8A0445CADFA39B9AB8D4201AD00AA424B8B6EE8CF2A815CCE0BF234F7F42E07BB754331D7E192D132960326CD57BBD56FC5A9EA2BD5E7C87ADA9F061DC9EA7E9EB88F40E899E44D3558FB9B16C7F0DF9A25BB1E5EE0C6C3651D5861C94769EB7D57B84217DD7ABE8A4386890487E70ADEDD11CB102689BE77A6F73BF11287E65076000935EDC758E191D6DDE89296675746AA7CA36F87FFFFEAC5CB3F9081DEDA46C0F04EFB15F980FCC2C3D787F81DF668AE9A10FCA5016598D24771FA93AFEF4284E4364A0D54FDF5AB780E85CDEE0554F26C870B91B00E945AC32415B23EA3EF30D6E5E48EB871E83B16C9BDC06B141B53E4C09554DF988170CEF09D3CDA9E5A6014C1DD5B74CB95CDB94CC24B71297E8CCEF720F1B0EA62AA5A53C730D3DBC8FCFE29F706C7E70AE7FC258D6CE7F9A3722DC473DD3A41F807C4D6E99AB2FEDB28039A09319EDD077042075AB4E37E03DEBA5E875DC2384E5AA5C32F68C2D385E9B4A2B46DE6BFFA5B92E105F44CC41FD28D7080540B342649710EC859F9E8D06C70A1DC7C28D162089C2321A899320C1CB75A0110759E1323197738C775C7B23B8CF52F24872ABF4AA6D37CBC9723E9C32996C2DB34346A3CA44924ECECA05916C1BF1A64D817EB1C6CEB1B831BFE6779DFDCDD3E5E04328FCF3AADCFDB7EA1A70E1D461FF3EF600856D4F13DEC927809C9B060605FEA3A1C36477C833EE58A3ADB47CD339C23163ED28F65C407D98D2EB6B93B17EBA8B0C80E789090FCBBA28E9CC9257764CB505E071DEB6F6E1BA54D049E68BA58C12526964C7028AA1C0D428451A6E2B9539B83F21A161FC955247441D5E2F5301D588D8EE489C6ED536E20E155E1AA4558F3C9C04E285335DCBB314FE9F5EA95984A1C4CCA1A6776FBB09F54216647701984F8FC385E61B36E22BD3D247D21E0AA0C4A87024BC80D0732D48A153473765A8D27D251DFA48CFC087B494E0B62885146CFC6BC972915B2038EB699CA389367479EFB41E4AB283238BF18EE953D1511F0BAE0F0D81630E56A727CD9AAC85FA266369C62A1C2E39383A1306091274F77C0F120AAB529965778FE143457A0D0B7DBD4AC56D1AAB570E1D4B74D3773BD6BBD7CE8AF97B8E892F222290AC5BBB83AFC2F4557F2EFB844C9F460CFAD1CDE9E152EC52F422A6905F280CBAED45BDE910DFB2950C39C29F80EB6872D14DDD5F88FFBEDF79A35D16DFF7944A292BDF1A1D104C59B4B2DB55CE817F2AF539F0D5E14B3F7F45E8812F519BEE3A24BED6FF6C6F42306BBEB0FBE70F9F8E74EA3B32B1EBFCD9C2BBE30F4A87A4A202975DD0BFA6BDE4196AEAE10DACA585CCAB4F4BE966C1EC2180892A05706721B2886DF16E22121FA7FDC833379B0EB33E3711A6940C1D345F19EB1DDE0923EA8AD12ADA44F31BF6B29B4A84C3651408DB9E2504C0A6DE81730AFDF959A149C113923F4F419ECEFA20CB79EC52210B8DB66C126A100AD2803E09ABAD29DEC3346A9BA364657257928A905225547501957DC73004B7196ED6BCD4EFC981EE8A2799A53D2B921DA98E9924BA7BB2186883FEA2AF3C06954236C540FCCBBBB470F73D219714C7B811233E153711496BC1278B1200927B79B11982504E5FC53B85E23ECF435570F645D5E9353E9718D493FB7C97CAB597ECA391DAB8FD534CA24B85891EBDF4ED9810E5EE38D7BF26AF7ADF72C5E35277E51D3088B4B8FC689237D12B5A3EF5644DA9FD7026BE2CF9569716E758208B1A5735DCE516DD14C05EA145D5C803F1C6195C22A088994418CF951292750CC276C819F5B1056B1D09DB11E8B37C79BB06DC2E2597CD5B9C97CACFF32F8F9626BC5D3E279E036BE74A07224E6EA8CC3926ED645C065E70D7610DD1405C0D1137CE799AF66EC05EFDE745293F28185B82BF835FB3746EE6FE92ED0A73E6B1B3BD5797E489B1C6E21BA624A45F82CDE96CA8976052BCB06E065A9C73AC9F8200DFAA8E754F5A4145E2257198C4123B88796CF77CC9B655741C9D0CC7C1FAF1CF4AD364F63EC10AF2C83AE5AF873D7FF97D51E0138E56EE9307E4559529DB5B322F5B3AA59202BBCAE8A2EBB01681E90D59EDA37BA4FE66735AB50C33EA54B3B29DA44E12D3380CDE5C7DEDC302BE49ED7C3441C5E370A43D1270905C978245B9598367CA1B65D72D757D494DD14004C224823A1658A745F12D009AF70137712560A5FD178DFCE01A4007B774333A8452D8F89749DB2880B98C572EA5B3BCD5E8BC75C74352010AC4DFC5F461326BD1CE92C87E54AB7214F7C8ACA886181E9F002E324C79D84938C539A0B5ABCEB44E5BBD3C6502666C10922357096C2DECD51CF76540838EBB60BF3A3872AC4FC2F2539FB690FB5D655295C772FD529CE9856CF0D4C22FF1B82345294209A12F4B9EEBFDFA07945C181C86E883908C0A662BE08B4B863287B9E9E05F51BFABB1EB3A342979E644FB60E84547FB954385B8BB2156DB032C9DBB5C3F0EF14E84E30A884049639861738D0A8E45FBE326048A98ACBD1398B525CF6435B73F1EA9B7DF96176EEA260A0000B5C9E3FA3FFF764CD1ED3A06ABE2AC20A7ACDEC2F7B8C4969401E6360A0347AF0C489C4A6773AF4235C39ED4637B29028EB73C0EF93C4E919ED283D59A14D941AED8B9FC64F4A2154C9C98118E5F8913454C0033672D7D32AA2015D28AE47B7DCE093CB83068675001C932F8EC4A7D65DC583C5BF53F180F11EF422A5D6CCC5911F042CAB7FBE1507F3DBA86537E71935753514EAF4846ECB33E82B4EBD24E8F3241E92757A9ED4A75DF774EB8A5507E90AB9FF53A344F08C31E2F57F85B5AFD271DA594E23A67C4175AB6941AAD38889A4C573D5A3C93DC70F244A73DC7DECEDC15C260D3901A3C05BE5F75E536AE4606773B0C43897146155C71D1C00DA2A526F8677C32CE4A7D76879DECAF36067E4DB2CCF1661B44070C00D01C29C9344C243D43470840F11C370F642EE44E72C693DD5C0FA17C3B069F378776B73044AF8D483F14C8FAF5FCD7E279F9CD18A45D700820958F3F98F79F843FC0599BEC3039CDA8CB33F2A0539B5477C84EEA9289651760D2501DB24B3C661BF018EFF817203310DEDD0C2CAC6F3F6457235D84A8C626CD2565F588ABD70433BF419E2CE25E0F96DFD1FB32C6307A1997B7BD275C3E717C9681D23620259964EDA5A7C582B5C616D71D0C73C9D1E4E21FAD548DB6923D1BFC5D74523C4581EAD84D37C0F0A8466760A7439522C3291805FE11CDDA13C0DBA94210C6A8D7B24D66F2D79D771DB1C32E4A06598A1585D4C79CC34354AF2ECEF5995A610C289F37C5F4AE7B550ECD60E90CEB69D21CCD366A29D70395F0DE991A33B4D8800EC0E444222D8C48A6BBD958583C6BCD68D27F618F6FED62ADFFC7B2817CF397D17E411F09817E1D7B2CE4A965571D7C8F466707AF0AE244422F8B303DFB36AC7F828B0ACC732C9C3BDA6E0677390BC9676FEAB51E631D9C53811F002731EDCA721FD098527DA5F1FE6541DAFA880627BA365235D33BCAAC78B82C13587EFC7A0B446EEB3E52464F38E3F94A21E4E24F8658F156D957D1FE636DB6D2B72A14FE84C427883C346A0C641EBC5655AB78852E9FCCCDA6A38E85E4D30F62836A69118D339722E33CED531EB8B3735F5D84D95AD1D6A16ED4CB070C4823F94A3E59856C71DC1B0A4C7D979D5FE84DA3AF3FBB83C6E5A21E86E4D137615DFF6ED022B478A79BD6801CFC6F62F299C0D1CAECE6F98E99E677A7658F239BDD6F94071BE816267FA850BF4B42F9A9D90A7CB7177CF368A8379ACC76DDD4229039CEEDDE89560E9054349E77B17ADE0F45CF28F8DEFA425153347F78A858A1EB832AFEA3CEB72DC3907A399FA9EDCDBCA5B6062E4AF5BD2028B4A638C03E1D8B5D45E5B11D1FC50B4E2CA2AFAC3C5BF9783B7848E1090B9991686F412B5CE2B7C8DCA04310D1B1A0BA2E3BC0F0B86E974A8114A37C35C72359AA63D500BBC50DC511FC0B3A54627D708D8D2FABC297185DB7B279D1337B08E1FCEB30BCB69DA8A006527E519992274465E50DC2E1627F2756FEFAF46A150ACE7F1FFE8501112E4CA916482F98051D84E3F0D0B9196B7A1982A3B8C66E6EABF58B583ED704FF3584ACF7FEB5DD62E9542C6FDA2361CDE4BDA77C547D34223C9A7A4986B24FFDAD6F23E804724782008FD804B70D291E53FF44E8861D9126E9FE2B377A48CE0F26EA453E877064E2038943C138E0F3F2A550AAA60CFAD81B0E1A0CD580EAA15D48883305547D535767FED2441C8EFE1E5067B01959276B809E989299FB0E5C05FE9726A1781414009A1304D7AAB4C832735F26B7C22214077629F9769C365DADAB7518F547B1264B823F23A16271142D29BEE48AD5CF51FE699AD77BF1CBBB2F1CB25D80D7CFD40EA0E4D06529D720969A1DFB52201B411F4560E03B05B4EA7A8CEF5D4A3F7D31ABF367210103B0032E77A3EEC1D97E178D038EC58A58B5EF879BBBAB53FE1348A15DA6507BE2CAC71D15357529CC9602E7633530FB0ED98AA70843D86783AA3C21B33515F19EC0DC0C6BA5ACA96BF38E04163B7B459983038DB0BFD90583540DF5E2199C65BAB582C631806B134AF5D6595598C1D415F79E7A485AE6F78447E29FF81D404888D37170E42DD13F4BE90C16C8CB2BDB2EC8358CD9051AC0DA078D057DEFCFE3EDDA783DA92CC208F3B86DF3CF72C0F3C859A693562383EA754EB254630CB5089585030033C66759E87116CF9D681DF365EEE989226C2956A0F78E9928E435172F6E00737418344EEC208BCBB159D8123CB8912F6A337CBEA5B03CE98D3ADC33356C96CD4264CDE5CCDE1EB27F6002C46691D4827BFED9972A6BAC4987C6432BB411C8F9F52A774ADDFF2C7F53E49EDA739B1CF2EF13C75D62C3053189CC0B5C3722ED1C1F3415CCC977BBDA6B2B2F2944EE735D13B8C31955B9CC0DE77D541C9F765B01521970DBDFCF96F80705378524743FB2FE1356C9CFEE33D90B75B3CD0FCDD5920DC5A19C6C369F774EEFFF8F37D4BAC8758DC77E6A4644146EB1557529D35FF1B4B1778814BD65E4C735908E402190C8E1C80FF96D0A626DF599FD6F14EE8E595FFDB3C97C29AA36E14B249FD79AD8D812077F72EE39EDB740C00825404DA06CB27526F49CEB9DF4BFEE3E0622D8B59ED11D6E52DD011825C94A866D064B77D504344997F0A0CFB610E3FA10535127AEC1C67F87751DE7173BFE53E3597177128106CD1F241FC8F27C847E67BEF419D2B77F6B665700BB1C96B5F4775C994DC7341D7F8525C94FC41830C89CEA1B69DD68838113015F509D3A81BFC0C2F4D3145FFB5BA4F852782E43056D1A65D9F4B9F770ED4356785C8A36E33BE3D5AEF7069AC3F4696B4B65C154CA46D2A89BBDD7107416D05FD1649D82B8755B7B80E6824E19DE730F895F6B60D6E63E64D65310B59C2B4453DB2AC03A33BD045E304AA22D87DB448521685475469A25EC0811FC745A2AD52618E8DD9807674F9D26067F7B846BCBBE83A7B3FFCFD13587276F44E4CF8BA0BF1FAFED3DB1FD26801F4C66180EACE5C5B9EEEAA028A994B6F062CEFA91EF118F0B4BA1F99289D7AF83861BA4C736706A90354261EF1ABE9611D4F06996F6243F30CBA6CB2A00571A91D48FC84F66C466B660DF77822CCE184D1CB313ED78AD95EE904CC0DE27B9DA8CE49DDD6615289B2C567B71108045ED5534CCCA6CF46A2DCAF273215D2930D7590BCC975E8A44C726B737219D4CACE47D302F451EF7653A63ED90772FA4691847CCAE68F3581AFCFF08E0E1174769380DF40BF25A1F3FD2D85A88DE3BB702F8147DE60A8CB509970FAB172F2E1682DE3282F03D2E6B8AC6C7B98B98F85F0027CCD47D90F2BABC55AAAA4724A08B365ECE8AA7D8373C76141CC56D64F43379984277BA03B2BC954DE3CF06812FBA6C462E583652049BD37276B0897522E3B0B6BCDF4D8D032E0F6DFA7E6E388A2DBBEFAD7B58E5487321CFE6AFF39C3E7C0FBFD6ED848557C2952CF5FDB03D99E0C2F112077502841D1DD4905B5056E4B202D94B95CDD2D798FDA38CAE3A51E8C14809C7E7CA70316CEBECB25F250B62D54646FA5A62339B2BE43F273488DBD350D334B34AEACBAED01BE424D02C1244C52245B746DA0A6BD092170EF7E4C6B4AA5C449AB11B4879215134E57D06DCFC980F1589ACA45818B186614B0432E698354C4EAA6E5FD8D1CD5C11F0315982EE1522CC6F22D8557CC3DBE64397352EDB9AB247E6F0819E548502A50BB379B5B8432F9B04FDCD7A5EE670694386DAE4DF491EE807D3783E86221408B51B8D3EB8FDD0878E9797F830D95697B9E270422698A77914F59B58E739A171F4BF7BB012572B05CFB66051E32EC69239EEE0248FEEC2AF7B13977B1DC7070043FB099E04C4B2B610EA199922E7D29B766881E8391DD8FD9E26305DBDF963D8929D470157CA6A0216D6E2DA0022796F62C944E98498DF04A252889A93EE6AA55300C1DE6AE5E1C2D499F9EE6C080C5B5A77F4BA851491FECEC268D407299A502F7672CB60E685D50DCB92E309ED85F3088B03E774E964571E846C78CBC75D48BA46598E70D142529D3A04E395E72B7292E961E2BAF0101EA4E54318292CCBE1A499354A8AC656F72AED89B31B54ABA8E149CEC378ACFC6E1D98552323BB7EF439259C0A28AE4EFF217DD09F91C777618917C644B0A265CB6D85001DF9193F89854C1E10C62143BE9ECB3A1EB29E368B6141824C0216EA7DC15F51AE424CCFB6FED85CEB23FD67B338D0D24A9FD70C1610715919F2AC45C6B5D441815555D5D73BE70815AFCC8B0A4C1147D82746DC7E7D866379FE60CB2B444B80E568E0361EF5DD55523D0193BD11C0D90615E5B504F56507499BAE78D117578AEE8EE86BF103D51BABE09B777B9A23F05C0018CFCCF2907874038846A658F3E71356776BB598D1DE55FC9885E49985E12CC7FC8F7BED04C24E48CFE2F671322610B435C09907016E3EBC95EFF5ECD1F4FA8253A1AD5487F1A3663A27958670E5ECB971CDE9B3272ED49C13DEA51161168FA1A9459F97CDB568DD3676DC232C0BDAF07CEBEDFD92E9A152E669B2EFE0029AC28B7B64B792F4EB6FB173BD7F7FE750D78E18FAA1F21D4A87BF888D09D36EAA274D499556BE00361EB83AA870B2BC534575633F7FE93C4BE97A20E58011BA1B39E086C78D54DB1DA94404548472C7E9BE9E86E1273C129E5A909E4D01FBC8A336065CFFA60A233DE79B15EE863FE80F3365E35802C7DC2D1B1C3E3194BA7185F8EC46230F5893BF802A83D045F2E131546B2D096A4D66F144E26A8FA8EB494EEEDFF899F4D4930F0CA5A006FC0C2CF90375DF12B56DA8F7A5A346ECBCFD519DFD01A1BE4FE893B66F099456D7A03B92FAC57C348D4B75C34F341937F1E665354057AD180C1A1A69EA24A410ADEAAD1E3E0F633D6D7A56BB2153D2D29EB029B42C7DE777284DB524F2711A51F57D1BDA7BA587C2EF745EA867CF4BD12F05436F929C77970EEABC849F15AB717EAA5A614D67F7C86E8F5D331CA9EB7DDA110E5852AFA86091C61DC2CE98A232DB9DE4051C92BB23C9B0FB6B46B3995F66562F44E541950E0E9C5EBC86D565C4DCCDAD128F7E7432E9C9B9D38E31309B26F1FED6BC2680190BE12D1C257AD50E41BFF1B3F30DC16A4A870A4D48098102B50F08DF015BD0CE9051B55107774B78B20E2CBE264671662C84CB9F27C43A8BCE6FC06B73316A21FD83D4397F01F600B72A0C0DDA6BC77532FE3744E5563EEF8CB2525DFF2E1A303DDDA6C15B74B534C95FC8C9257930ECC7EF28248E5C8660BC34A87DDA051155302BB1CFA1AEA72830B9982B2527FA33A23F068816CE4C5D04523FC22BF727EA25280AA7A4AFDD48102E78D758EEB3C56F9A17F6C022ACC369E359EC9E4C9280C6AC09D0C73AB1C0BB6C96F11E6074346290FF0452D9A9311733CF5FC698DAD10D2DFF3187C293BA4EEC05F981AA5461A5E098C8EC25C1EC7DF15D2BFF23591E89EB9E49BE297754E2F4130FFACDF00570C617AED7A32EC8C9FF5120B26A8079F1E565FBCC7E695029214CF12417733E2CB1C3FA09174DFBAE59F2C8A2585A68EB9629087B57FEF0B289C9564CF904DFEB9E17F2A6B9AB52AA9CB61913A4E74E4B34E3A8343CCC83379CBCA28F70209BD3110A0EEBB9027109562C9C184B93377191E72FB868C07F0503E5EE2FA8E139F4E3D29B19E3510525131F0C6C25C49BE4F1DFA7AF5FB7B43E49D663A17CF37B826E4CC3104610A4624E802CB80A1D1225738D2324C4B27D3736D92E5698B96B38FA502EA146EB147B4A90DEC15BB7F734A0DBA7BB5D3BC2EF2679214572F795085E83007C90323942914A0139113DD675E9F1CD871D45C92B1A4D8B6A0C0FE4DECFCB4D8EC81206B0F1A23814E2371D4D3F0FC81DEE289DE8322917ACA096DA1BB10CDCF912CEDA633BA0DD4EDF7D30642944A34A51A449936BD0C3A8DC99399E63748E3C4E37F3DE37CE1C41776B6C8B12C644CBC45F3714926DA240DD5A2960F9E93173E25FFAC713AE07827DA98C1C0F1A558C6E26E42C327623EB74A1700F9AF633339AB28889F3D0E624652E008919B4A97D161E5865FCBF2972BE191D1C86C878E88BC3D50D7D0AE9CF37424146306488D6472EA949A0EB5515C1146EDFFC6E4B4C5CD750481B44EB600952BD45F097DBC713E88ACDB1338677E19351CBC4D52F24FE44048EAFA7C70F0128E5F115B5516D04EB34719857BC7CC33F0EB26BD325F62D14412B37C72BC21266E54211D47BEAAB01A87056E9B9AD88CDB8305AB52FD6191666F6D136C273C75C77ACB5FE119DD21C70F4FFAB7B4CEA7B316E2FFCC4C6EB2BD3DF1044A16D3D609BF6E19B01C0CE035175148BA780C6E509E8458329B1AEDF9F02E25BA03E8DE3A5CB1E120453D55A2696A46F5FEAAC49025473ED01478BCBFB0BFAFC969EB37550B022A58B4D13D2F8BA58532DA9BC1186666AB017A7B9246B3FBA75926A4C72B97F8AF4B27946FEDC5A07554CBD1A792D5DBB0591F04B53343CEC496AA418A00A5300421A90394553CD2C3EB70A51B1DCE6C0CC0BFF99DCB8F2771597DC270A1911A23C606DF36A7EFECBE0A00B9FD7FBF6586BA9D770A3C3D6DEAB357E307973E38582CE2A88B868CD291986B97C3040AF48477C586E6AE0BD76A209AA263824344C861B56CED6D4026C9A1DAD1BB9FDB71386B2751255BD6BFF9C02B59DEFADBAF2CB214DB79B6972692DF3A157243431F2BF7FC62048A935D3D392B9A8D52904E66095227C82D625DA9D86E3A9A9F5D881021E8E70187B60040E89200BA35EFEE309F06C8A91C341C46FC3F145B8E125D265EC24AF88EEACCFAB3D227FE9B3EF04B2C661A21FB7721A2CC43DB7BAB904B01BF72DF0602E4C1192AE5BE3EABC5347E2B861D0700AAD018338FF893566CCA1B2BFDCF486F5FF5D54D9DC6B89FCD555AD387A38D175F77AA055A02A6C130885E8F666D9D7145B4D396BC1C2AB9204608C78AEB66DA17EDF8DD395C59DE1FF3F81B5D64663F9322365FBE553E8C1AFFCE2B41C7AA3EF9798E783B80D231CF97F0CB7B5616844D8D0E934180815A8050D697E062566D5AB39B62CF2BA528C302734F945C776473D53E8CBEE5D903E1295D28DE187ABAC4808C748401F61C6D4512B605A646E2E6502FF245DF7A88525F6D9527084E87AE7738BBEBC9CEE78D3FA217BB13F0CAFEF786B448E6C8A28AA6B871ED827D9569E20F60D4475A750BE65A4706598118004200E9151FDE421AAA5C2A3DAE8CAF96E98A8DDCCABDD2176B8DD2BF59B3D0FBA841DDFC74BD7E26B381AD02621D7487040A042B049532196D5EB778A254DD782F87831C81D94A81E909FB74B48680D1C803FAAF96A0CA260A24F21FEDEA3099AC9FCC83E679CEAB2A22AE1F5B0C6850AB0BE7894E886E5422234D05767CDB2A22BBC226A243EBB8C937E4F8212F674A7469FD8022E1F245C1FDD23569A8CA34D8BB5346B95E683A16F9494801957A5166373B9375EDCFE44C1A0947355600F22434C1B9DBE01847D3DDCD9232A56670F00574234BC1643BE0F4D9BFC0950D81C1A31C6B348B2268743076380B1AF99CA3AAEA618A955CBA32E2B97F41EEBA2928EA568DFA5F783B2BE02CBE12FD147A1382E9ABE2F7173D570393C06C0C2F8A4ADF7B7953152D3EBBA7EDEFB50C08FC8D3AE64698619C14F5626AF218301953A69FE005AB930539ED693B091C3D130B29B98CDE85C32649634E457801BE427B712BC7B9E5D4584EBE3E8C8CA800569735B6EDE1EB7B3AF8A033BE5F7B02E0BD70870F766581551B59447EC13618F94CB9C862D924FA688B1C6DEEBEA08802AC66FF7B986BD832C5A8C80E44F56727652AFB0F95FA93DE0F754470046C123AA1CD7BABC5870EA715C82A55E9C4F6E49B56497E4D696B84360348AF11A25DFEC2550705D519FEC9D14428FC5392F7416E8A3441C7E84B676BCC6736FC5092F752461B1461D444141AF8AB986BB23ED75220CD70BBB71E3086F95177943D0299DF3F2E97FE8C2F4F5C19156CF377A9A72BFAFC7AC2CFB4951A93D94B090B2AEFB3E9F6C8F4DE04802D2E13E613C9BC0DF40DF5FA53DD5831B9E4F6B2C997E6BA6FBAE79BA434E371FED374555E80DCEEAC4B1B2CD3A859D99D7F29B8C3DC5799F8AF6F3F1FDD1DE9A5F137D731E3A70CFBA4126AF74FD3D5DAF7A2EDD7E201BC4FEFEACB537AAE25A0B6E165A51FE621F9F4FCAC11B40510CABA0DA82F2BA8EA4B1EE639E3A85B479A40192767CEC3FB686B81EC9F8FC71A320EEA51CD7C2808A7230D8A67BCB29405BFEA4E3E2261525282D3CF17D992D4B162580D5D9672668E941448263D67A7341BE50FCE58E9D0E814C967714553639AD883210F246D1F3CE615297D9D6EF66C814BFB1887AA1DAB86E3CA6CC22269B1102E0AFE85043E77D095D7DA4A8B838710D11190EF49E63459F7E57A9A01E105D99F606E89973B90DB3FE68B710D098682B00420F3D445E300C82A84482B6A3661EE02DC1F0FA65EF3A34BFF686FD65CB001D3F1E76D503CBA6A2A2E8D1D30F11B37212EACFEA0FF20D9CBA11F19D4F37ECCAC792858D620D146C2533DCDF2ED6B7EFF9319CE1C5560158C5797068055A0876A5D080C52EC1E87AE656A82D4A836E39A61F93CF2F72F1C20BF5D48B9878E80D09BAB74E250A6CDC09742DE6F6579E5FD73C4CDDD25A95EBC1719BE024BC8FE7E1AC12E0FAFF46785D1A93811A81F08E8FBB61BA2999C49B3E97A99EB0787B9466BC24B2CC7F1DEBA162A0484E70CAA64AFDC9D3FC4CBA6AAD3009367BBA2831E821057FC8E43C3A4016D93E1115BE137A8A6712DAFD012ADEA1385369676C58B0E219F85235138E74FA73D9393F618733CE4BA8D588B68D7879AA071BE80DFE27996F5957A736833CC24A6F87338C69F3D9F3863A3D7355FF965AE7E9FFD4F349C4CC4F2140F28435FBDE89FD759720BCC1BB5AD3C7E166FB41DBC6998929DD53C1FB3841CC8CA38610E11AAB4654938C890DC9F00BA3C1DC59A9457F13E750933A4258059B7FB4BAA89B0FBB1CB4E84B4593CCC250E5C23D2F6EC66F1B974901B6D75A73D2B067B7BAE3466EBB3F3FB21B589D2EC8ADE45CDD07C8974B6D84186E4117A56BA8C73D3B98838D338D22D169A903759FBFDC653D54DDFB1BFF7FFD3634B802A4036C4FFC819AC29B33F9920F8CD34F8ED11E1D21C624CC826003E2DFAD4624CE79DBE1081BDC01ED527E731240829108CC0D0EF7A20CC528E5EFDD7258B2222B97F31C1E9E4BFC19381B70CE1D9D9AB2D79DB5D6C96F1B91C92BDEAC9A4633655A6C4BB0508EFC53D665828321CB82782C7B0C1B48F5FDA2AF2A83F30ADDFE23E648234B9BCA4AD3D4CD1D6CEBAC39C3B87C4D5C4DC8AAA48E4BC3168D00CC8B6F04F87FA9957A4E2D894346BA9FD4D931C14774FCF7D2610EBFF687F4EE4441C1B8FE84A2C5EAA9CAC071A8061C29B1C48273DC35475BD4C82A72DB9853DBECFB0E7CAF4C2C0654255EB5B994235CAE8E908C671BCF4F2E33CC7A08C7814B8A92D6260E444EAC0B0C983A4241F7D4AF78DEC16C7B078D20F57A48FE100DFC64EFB9AB50BC2ED379B455865EEEE109AFE5B23D563FFDE07858601C8FCAF5FDF2B102E70D830CC74672D92065BF026631DBDD67DAC4380BE6B33D117DBB74FCFC899EC614709D83CF9C821E3E1571EBA0FCFF396E3108F508544CC9022455C79D4D3D72FC6958BFA3F67ECBC4A2C961E4AC882F9B73EFDAF92DE61BD9A829A37012A3ADB642E890807865F8D14A51EAA07AF561F16AA44DE655C4DC87E4B1EF95F3B09F45B43823611A14E345D739FB83136339DA50EE3AA53EBB6B9625BB6248DBF7075F52345D597E7304FB3B9A56115D160B99DE111C78664533E249C4BB7B7335DE6F6BA94A7E30C5A2EF3DC7E4D402F704C6D81D7071BC1D299DDE6109C4458100EC83B3E2517280C8C0B72E43A842ECB54894151882ED95DADFBEFDC45FDCF92017D3271920ACB5165590CDF9F269BCB2C997541C06F3C5BF29F0BBC1E21B6D51FB091CD53C3855EC5A41348F21D4947D876795848DDEAB4240735935AE5333CA0E0B07F1A9BBE5A3B139FA6FE1D0D03EE410917FDA57251FAE218F3E7FFC2C85D15D494F9EC4BF8E4E38A9D0B23EA2D115B2B3BB16CF1A18AC411F38966A20E5332C0A36EB86D5C9761EDEAF6D162C307EA17C3FBBB99D2806DFE161F2D45969E9C680C8FA023EDC41394AA21D787897016F5903E063D99FB70E7620A6BDB0BFF1FAC7D72EC631102F86AFAA6E17817A4B64FC3496B1E5858B96D8150A32915A6EC286296D3DD6D92417FE9DD11B9B685DFBAEB2A4CE9F0797DA68525D56E511DAF946A70E0AE72FEA2757E1DA0DD93E88D911F526760474D61188BE1140E69A281465A88FA82FB14EF92F8EB69C64EE3FA49BBD5C038CF5057A0FE83E46EDFB5C93E04B682159144FFF0C8BDB0B636403B705ED815B4990D2045C40E8A01CDAB2693A966567B1ACDFAFD353A94F7F468E2CBF64026E661E4AA3DBA0F1437E5F865A74F207EE8D8178459BE18FC6D8CDACC857847DA05B9514CAC0BC6C6341A45779F0D349BCB096CCBECAE4859ACA4E15A8D2C3056860434C5601F5D40E1B670E812835B086C5474BC4755D5484E45B98F5DB8EB26FDCBB346A014021C47B04FA38DBD1AE78B413CC6E10940541F1E8B869CD7B64989319E39A9FA5B69FC7356393224FE229ED08518730B2BC435482731A9E10DF998B1C32EBC902B3000E87260FA41792A15BBF635256821F32FCDC7E74400F97FE2224968190218739663D8F3024F16CF8F222B7E170ECA64FF6B743A9B7E425FAAB21C0A8936E50FAEFF402E8D41CCEC1B74904A3AE233DE49EDDCA509291104A5E011E993F0AEB2EF356A3940A6E8D9D17AC7FF4339A8F92142094891C236348695D2565FDFCECD7CDAB3DE13B9B73C8F97608470ED4182A14BD2D8B3673ACA9ACBB37F9D91067F795503B6512D6741F093C5D887D8844F7E1894013E3DCF444A7C8ED79165BEA99D6CB05EC",
        .algId = CRYPT_PKEY_SLH_DSA,
        .preHashId = CRYPT_MD_SHA256,
        .type = CRYPT_SLH_DSA_SHA2_128F,
    }
};

static int32_t GetPkey(void *libCtx, const char *attrName, const CMVP_SlhdsaSignVector *vector,
    CRYPT_EAL_PkeyCtx **pkeyPrv, CRYPT_EAL_PkeyCtx **pkeyPub)
{
    int32_t ret = CRYPT_CMVP_ERR_ALGO_SELFTEST;
    CRYPT_EAL_PkeyPrv prvKey = { 0 };
    uint8_t *rand = NULL;
    uint8_t *vectorKey = NULL;
    uint8_t *context = NULL;
    *pkeyPrv = CRYPT_EAL_ProviderPkeyNewCtx(libCtx, vector->algId, 0, attrName);
    GOTO_ERR_IF_TRUE(*pkeyPrv == NULL, CRYPT_CMVP_ERR_ALGO_SELFTEST);
    *pkeyPub = CRYPT_EAL_ProviderPkeyNewCtx(libCtx, vector->algId, 0, attrName);
    GOTO_ERR_IF_TRUE(*pkeyPub == NULL, CRYPT_CMVP_ERR_ALGO_SELFTEST);

    ret = CRYPT_EAL_PkeySetParaById(*pkeyPrv, vector->type);
    GOTO_ERR_IF_TRUE(ret != CRYPT_SUCCESS, ret);
    ret = CRYPT_EAL_PkeySetParaById(*pkeyPub, vector->type);
    GOTO_ERR_IF_TRUE(ret != CRYPT_SUCCESS, ret);

    uint32_t keyLen = 0;
    ret = CRYPT_EAL_PkeyCtrl(*pkeyPrv, CRYPT_CTRL_GET_SLH_DSA_KEY_LEN, (void *)&keyLen, sizeof(keyLen));

    uint32_t randLen = 0;
    rand = CMVP_StringsToBins(vector->rnd, &randLen);
    ret = CRYPT_EAL_PkeyCtrl(*pkeyPrv, CRYPT_CTRL_SET_SLH_DSA_ADDRAND, (void *)rand, randLen);
    GOTO_ERR_IF_TRUE(ret != CRYPT_SUCCESS, ret);

    uint32_t vectorKeyLen = 0;
    vectorKey = CMVP_StringsToBins(vector->sk, &vectorKeyLen);
    prvKey.id = CRYPT_PKEY_SLH_DSA;
    prvKey.key.slhDsaPrv.seed = vectorKey;
    prvKey.key.slhDsaPrv.prf = vectorKey + keyLen;
    prvKey.key.slhDsaPrv.pub.seed = vectorKey + keyLen * 2; // 2: pub.seed offset
    prvKey.key.slhDsaPrv.pub.root = vectorKey + keyLen * 3; // 3: pub.root offset
    prvKey.key.slhDsaPrv.pub.len = keyLen;
    ret = CRYPT_EAL_PkeySetPrv(*pkeyPrv, &prvKey);
    GOTO_ERR_IF_TRUE(ret != CRYPT_SUCCESS, ret);
    uint32_t contextLen = 0;
    context = CMVP_StringsToBins(vector->context, &contextLen);
    ret = CRYPT_EAL_PkeyCtrl(*pkeyPrv, CRYPT_CTRL_SET_CTX_INFO, context, contextLen);
    GOTO_ERR_IF_TRUE(ret != CRYPT_SUCCESS, ret);

    ret = CRYPT_EAL_PkeyCtrl(*pkeyPub, CRYPT_CTRL_SET_SLH_DSA_ADDRAND, (void *)rand, randLen);
    GOTO_ERR_IF_TRUE(ret != CRYPT_SUCCESS, ret);
    ret = CRYPT_EAL_PkeySetPrv(*pkeyPub, &prvKey); // The prvKey contains the public key, public key is used here.
    GOTO_ERR_IF_TRUE(ret != CRYPT_SUCCESS, ret);
    ret = CRYPT_EAL_PkeyCtrl(*pkeyPub, CRYPT_CTRL_SET_CTX_INFO, context, contextLen);
ERR:
    BSL_SAL_Free(rand);
    BSL_SAL_Free(vectorKey);
    BSL_SAL_Free(context);
    return ret;
}

static bool TestSlhdsaSignVerify(void *libCtx, const char *attrName, const CMVP_SlhdsaSignVector *vector)
{
    bool ret = false;
    uint8_t *sign = NULL;
    uint8_t *signVec = NULL;
    uint32_t signLen;
    uint32_t signVecLen = 0;
    uint8_t *msg = NULL;
    uint32_t msgLen;
    CRYPT_EAL_PkeyCtx *pkeyPrv = NULL;
    CRYPT_EAL_PkeyCtx *pkeyPub = NULL;

    GOTO_ERR_IF_TRUE(
        GetPkey(libCtx, attrName, vector, &pkeyPrv, &pkeyPub) != CRYPT_SUCCESS, CRYPT_CMVP_ERR_ALGO_SELFTEST);
    msg = CMVP_StringsToBins(vector->msg, &msgLen);
    GOTO_ERR_IF_TRUE(msg == NULL, CRYPT_CMVP_COMMON_ERR);
    signVec = CMVP_StringsToBins(vector->sig, &signVecLen);
    GOTO_ERR_IF_TRUE(signVec == NULL, CRYPT_CMVP_COMMON_ERR);
    signLen = signVecLen;
    sign = BSL_SAL_Malloc(signLen);
    GOTO_ERR_IF_TRUE(sign == NULL, CRYPT_MEM_ALLOC_FAIL);
    // sign
    GOTO_ERR_IF_TRUE(CRYPT_EAL_PkeySign(pkeyPrv, vector->preHashId, msg, msgLen, sign, &signLen) != CRYPT_SUCCESS,
        CRYPT_CMVP_ERR_ALGO_SELFTEST);

    // compare the signature
    GOTO_ERR_IF_TRUE(signLen != signVecLen, CRYPT_CMVP_ERR_ALGO_SELFTEST);
    GOTO_ERR_IF_TRUE(memcmp(signVec, sign, signLen) != 0, CRYPT_CMVP_ERR_ALGO_SELFTEST);

    // verify
    GOTO_ERR_IF_TRUE(CRYPT_EAL_PkeyVerify(pkeyPub, vector->preHashId, msg, msgLen, sign, signLen) != CRYPT_SUCCESS,
        CRYPT_CMVP_ERR_ALGO_SELFTEST);
    ret = true;
ERR:
    BSL_SAL_Free(sign);
    BSL_SAL_Free(signVec);
    BSL_SAL_Free(msg);
    CRYPT_EAL_PkeyFreeCtx(pkeyPrv);
    CRYPT_EAL_PkeyFreeCtx(pkeyPub);
    return ret;
}

bool CRYPT_CMVP_SelftestSlhdsaSignVerify(void)
{
    bool ret = TestSlhdsaSignVerify(NULL, NULL, &SLHDSA_VECTOR[0]);
    return ret;
}

bool CRYPT_CMVP_SelftestProviderSlhdsaSignVerify(void *libCtx, const char *attrName)
{
    return TestSlhdsaSignVerify(libCtx, attrName, &SLHDSA_VECTOR[0]);
}
#endif /* HITLS_CRYPTO_CMVP_ISO19790 || HITLS_CRYPTO_CMVP_FIPS */